<?php

namespace App\Models;

use Illuminate\Database\Eloquent\Model;
use Illuminate\Database\Eloquent\SoftDeletes;
use Illuminate\Database\Eloquent\Relations\BelongsTo;
use Illuminate\Database\Eloquent\Relations\BelongsToMany;
use Illuminate\Database\Eloquent\Relations\HasMany;
use Spatie\Sluggable\HasSlug;
use Spatie\Sluggable\SlugOptions;
// use Laravel\Scout\Searchable;

class Post extends Model
{
    use SoftDeletes, HasSlug; // , Searchable

    protected $fillable = [
        'user_id',
        'category_id',
        'title',
        'slug',
        'excerpt',
        'content',
        'featured_image',
        'status',
        'access_level',
        'allow_comments',
        'is_approved',
        'approved_at',
        'approved_by',
        'rejected_reason',
        'reading_time',
        'password',
        'published_at',
        'views_count',
        'likes_count',
        'comments_count',
        'is_featured',
        'is_sticky',
        'meta_title',
        'meta_description',
        'meta_keywords',
    ];

    protected $casts = [
        'published_at' => 'datetime',
        'approved_at' => 'datetime',
        'is_featured' => 'boolean',
        'is_sticky' => 'boolean',
        'is_approved' => 'boolean',
        'allow_comments' => 'boolean',
        'views_count' => 'integer',
        'likes_count' => 'integer',
        'comments_count' => 'integer',
        'reading_time' => 'integer',
    ];

    protected $appends = ['reading_time'];

    public function getSlugOptions(): SlugOptions
    {
        return SlugOptions::create()
            ->generateSlugsFrom('title')
            ->saveSlugsTo('slug');
    }

    public function toSearchableArray()
    {
        return [
            'id' => $this->id,
            'title' => $this->title,
            'content' => strip_tags($this->content),
            'excerpt' => $this->excerpt,
        ];
    }

    public function user(): BelongsTo
    {
        return $this->belongsTo(User::class);
    }

    public function category(): BelongsTo
    {
        return $this->belongsTo(Category::class);
    }

    public function tags(): BelongsToMany
    {
        return $this->belongsToMany(Tag::class);
    }

    public function comments(): HasMany
    {
        return $this->hasMany(Comment::class);
    }

    public function likes(): HasMany
    {
        return $this->hasMany(PostLike::class);
    }

    public function favorites(): HasMany
    {
        return $this->hasMany(PostFavorite::class);
    }

    public function likedBy(User $user): bool
    {
        return $this->likes()->where('user_id', $user->id)->exists();
    }

    public function favoritedBy(User $user): bool
    {
        return $this->favorites()->where('user_id', $user->id)->exists();
    }

    public function scopePublished($query)
    {
        return $query->where('status', 'published')
            ->where('published_at', '<=', now());
    }

    public function scopeFeatured($query)
    {
        return $query->where('is_featured', true);
    }

    public function scopePopular($query)
    {
        return $query->orderBy('views_count', 'desc');
    }

    public function incrementViewCount()
    {
        $this->increment('views_count');
    }

    public function isPublished(): bool
    {
        return $this->status === 'published' && $this->published_at <= now();
    }

    public function getReadingTimeAttribute(): int
    {
        $words = str_word_count(strip_tags($this->content));
        return ceil($words / 200); // 假设每分钟阅读200个单词
    }

    public function getExcerptAttribute($value)
    {
        return $value ?: \Str::limit(strip_tags($this->content), 200);
    }

    /**
     * 获取浏览者
     */
    public function viewers(): BelongsToMany
    {
        return $this->belongsToMany(User::class, 'post_views')
                    ->withPivot(['viewed_at', 'last_viewed_at', 'view_count', 'read_duration', 'read_progress']);
    }

    /**
     * 获取审核人
     */
    public function approvedBy(): BelongsTo
    {
        return $this->belongsTo(User::class, 'approved_by');
    }

    /**
     * 根据用户权限获取内容
     */
    public function getContentForUser(?User $user = null): string
    {
        // 如果是作者或管理员，显示完整内容
        if ($user && ($user->id === $this->user_id || in_array($user->role, ['admin', 'editor']))) {
            return $this->content;
        }

        // 根据访问级别决定显示内容
        switch ($this->access_level) {
            case 'public':
                return $this->content;

            case 'login_required':
                if (!$user) {
                    // 未登录用户只显示前50%的内容
                    $content = strip_tags($this->content);
                    $halfLength = (int) (strlen($content) / 2);
                    return substr($this->content, 0, $halfLength) .
                           "\n\n<p class='text-gray-500 italic'>登录后查看完整内容...</p>";
                }
                return $this->content;

            case 'followers_only':
                if (!$user || !$user->isFollowing($this->user)) {
                    return "<p class='text-gray-500 italic'>此内容仅关注者可见，请先关注作者。</p>";
                }
                return $this->content;

            case 'private':
                if (!$user || $user->id !== $this->user_id) {
                    return "<p class='text-gray-500 italic'>此内容为私密内容。</p>";
                }
                return $this->content;

            default:
                return $this->content;
        }
    }

    /**
     * Scope for approved posts
     */
    public function scopeApproved($query)
    {
        return $query->where('is_approved', true);
    }

    /**
     * Scope for posts accessible by user
     */
    public function scopeAccessibleBy($query, ?User $user = null)
    {
        if (!$user) {
            // 游客只能看到公开文章
            return $query->where('access_level', 'public');
        }

        if (in_array($user->role, ['admin', 'editor'])) {
            // 管理员和编辑可以看到所有文章
            return $query;
        }

        // 普通用户可以看到：自己的文章、公开文章、需要登录的文章、关注的作者的仅关注者可见文章
        return $query->where(function ($q) use ($user) {
            $q->where('user_id', $user->id)
              ->orWhere('access_level', 'public')
              ->orWhere('access_level', 'login_required')
              ->orWhere(function ($subQuery) use ($user) {
                  $subQuery->where('access_level', 'followers_only')
                           ->whereIn('user_id', $user->following()->pluck('users.id'));
              });
        });
    }
}